package com.zzyl.framework.interceptor;


import cn.hutool.core.util.ObjectUtil;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.StringUtils;
import com.zzyl.common.utils.UserThreadLocal;
import com.zzyl.framework.web.service.TokenService;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
/**
 *
 * 定义一个拦截器拦截小程序的请求 实现handlerInterceptor接口
 *
 *
 * */
public class MemberInterceptor implements HandlerInterceptor {

  @Autowired
  private TokenService tokenService;

    public MemberInterceptor(TokenService tokenService) {
        this.tokenService = tokenService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //1.判断是不是controller请求, 如果不是就直接放行
       /* if(!(handler instanceof HandlerInterceptor)){
            return  true; //放行直接返回true
        }*/
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        //2.获取请求参数中的token
        //因为每次请求都会在请求头中携带token
        String token = request.getHeader("authorization");
        //3.判断token是否为空，为空就直接返回401,同时抛出异常认证失败
       if(StringUtils.isEmpty(token)){
           response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
           throw new BaseException("认证失败");
       }
       //4.解析token token的组成为 userid和nickname
        // 我们在登陆成功后使用tokenservice中的createToken方法生成token,其参数为一个map集合
        //将tokenService中的解析token方法公有
        Claims claims = tokenService.parseToken(token);
       // 5.判断claims是否为空，为空就直接返回401,同时抛出异常认证失败
       if(ObjectUtil.isEmpty(claims)){
           response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
           throw new BaseException("认证失败");
           //说明token失效
       }

       //6.解析token中的数据  根据userId是否解析成功，为空就直接返回401,同时抛出异常认证失败
        Long userId = Long.valueOf(claims.get("userId").toString());
       if(ObjectUtil.isEmpty(userId)){
           //userid 为空说明数据库中没有此用户
           response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
           throw new BaseException("认证失败");
       }
          // 7.将userid存入threadLocal中
        UserThreadLocal.set(userId);
     log.info("用户id为:"+userId);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           //移除线程变量
        UserThreadLocal.remove();
    }
}
